<?php if (!defined('INDEX')) { trigger_error("Index is not defined!", E_USER_ERROR); exit(); }
/**
 * Class - bookmarks iterator. Singletone.
 * @package      habrabookmarks
 *
 * @author       Max Kamashev <max.kamashev@floscoeli.com>
 * @copyright    floscoeli.com ©2009
 * @license      http://opensource.org/licenses/gpl-3.0.html
 * @version      SVN: $Id: Bookmarks.php 46 2009-04-21 04:54:04Z M.Kamashev $
 *
 * settings:     ts: 4 spaces, eof: lf (unix), codepage: UTF-8
 */
class Bookmarks implements Iterator {

    /**
     * Collection Bookmark object
     * @var mixed Bookmark
     */
    private $var = array();
    
    /**
     * Adding new bookmark
     * @param $url string
     * @param $title string
     * @param $date int UNIX_TIMESTAMP
     * @param $description string
     * @param $tags array string
     * @return array mixed Return Bookmark object || FALSE if error
     */
    public function add($url='', $title='', $date='', $description='', $tags=array()) {
        $bookmark = new Bookmark($url, $title, $date, $description, $tags);
        $this->var[] = $bookmark;
        return $bookmark;
    }

    /**
     * Clear all bookmarks from collection
     * @return bool
     */
    public function clear() {
        unset($this->var);
        $this->var = array();
        return TRUE;
    }

    /**
     * Return dump bookmarks (for debuging)
     * @return void
     */
    public function __toString() {
        return "class Bookmarks {" . var_export($this->var, TRUE) . "}\n";
    }   

    /**
     * Save all bookmarks into XML file 
     * @param $file string Full filename path
     * @example
     *  <habrabookmarks version="0.1">
     *      <bookmark>
     *          <url>http://floscoeli.com/</url>
     *          <title>Floscoeli</title>
     *          <date>12312154</date>
     *          <description>
     *              <![CDATA[Description site.
     *                  enable tags: br, a, b, i, u, s
     *              ]]>
     *          </description>
     *          <tags>
     *              <tag>site</tag>
     *              <tag>floscoeli</tag>
     *          </tags>
     *      </bookmark>
     *      <bookmark> 
     *          ....
     *      </bookmark>
     *  </habrabookmarks>
     *
     * @return bool 
     */
    public function saveXML($file) {
        if (empty($file)){
            throw new Exception("Empty filename", E_USER_WARNING);
            return FALSE;
        }
        try {
            $xml = new XMLWriter();
            $xml->openURI($file); 
        } catch (Exception $e) {
            throw new Exception("Error on write file: " . $file, E_USER_WARNING);
            return FALSE;
        }
        $xml->startDocument('1.0','utf-8'); 
        $xml->startElement('habrabookmarks');
        $xml->writeAttribute('version','0.1');
        foreach ($this->var as $bookmark) {
            $xml->startElement('bookmark');
                $xml->writeElement('url', $bookmark->getUrl());
                $xml->writeElement('title', $bookmark->getTitle());
                $xml->writeElement('date', $bookmark->getDate());
                $xml->startElement('description');
                    $xml->startCdata();
                    $xml->text($bookmark->getDescription());
                    $xml->endCdata();
                $xml->endElement(); //description
                $xml->startElement('tags');
                $tags = $bookmark->getTags();
                foreach ($tags as $tag) {
                    $xml->writeElement('tag', $tag);
                }
                $xml->endElement(); //tags
            $xml->endElement(); // bookmark
        }
        $xml->endElement(); // habrabookmarks
        $xml->endDocument();
        return TRUE;
    }

    /**
     * Load bookmarks from XML file
     * @param $file string Full filename path
     * @return bool
     */
    public function loadXML($file='') {
        if (empty($file)) {
            throw new Exception ("Empty filename", E_USER_WARNING);
            return FALSE;
        }
        if (!file_exists($file)) {
            throw new Exception ("Wrong filename: ". $file, E_USER_WARNING);
            return FALSE;
        }
        // Перед загрузкой новых данных, старые - удаляются!
        $this->clear();
        $xml = new XMLReader();
        $xml->open($file, 'utf-8');
        while ($xml->read()) {
            if ($xml->nodeType == XMLReader::ELEMENT) {
                if ($xml->name == 'bookmark') {
                    $bookmark = $this->add();
                }
                if ($xml->name == 'url') {
                    $bookmark->setUrl($xml->readString());
                } elseif ($xml->name == 'title') {
                    $bookmark->setTitle($xml->readString());
                } elseif ($xml->name == 'date') {
                    $bookmark->setDate($xml->readString());
                } elseif ($xml->name == 'description') {
                    $bookmark->setDescription($xml->readString());
                } elseif ($xml->name == 'tag') {
                    $bookmark->addTag($xml->readString());
                }
            }
        }
        return TRUE;
    }


    /**
     * Set current first item
     * @see Iterator#rewind()
     * @return void
     */
    public function rewind() {
        reset($this->var);
    }

    /**
     * Return current Bookmark
     * @see Iterator#current()
     * @return Bookmark
     */
    public function current() {
        $var = current($this->var);
        return $var;
    }

    /**
     * Return key current Bookmark
     * @see Iterator#key()
     * @return int
     */
    public function key() {
        $var = key($this->var);
        return $var;
    }

    /**
     * Return next Bookmark 
     * @see Iterator#next()
     * @return Bookmark
     */
    public function next() {
        $var = next($this->var);
        return $var;
    }

    /**
     * Validate current Bookmark
     * @see Iterator#valid()
     * @return bool
     */
    public function valid() {
        $var = $this->current() !== false;
        return $var;
    }
}
